/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import convert from './xml_js'
import expectData from './expectData'

const BASE_COUNT=100;
 
/* JavaScript objects are converted to xml strings */
function js2xml_Test_01() {    
    let jsData = {
        "vertical": {
          "_attributes": {
            "-display_name": "Exercise"
          },
          "html": {
            "_attributes": {
              "-url_name": "12345"
            }
          },
          "lti_consumer": {
            "_attributes": {
              "-url_name": "12345",
              "-xblock-family": "xblock.v1",
              "-accept_grades_past_due": "false",
              "-weight": "14.0",
              "-has_score": "true",
              "-display_name": "Exercise",
              "-ask_to_send_username": "true",
              "-ask_to_send_email": "true",
              "-button_text": "Launch Exercise",
              "-custom_parameters": "none",
              "-lti_id": "id",
              "-launch_target": "new_window",
              "-launch_url": "url"
            }
          }
        }
    } 
    let result
    let startTime = Date.now()
    for (let i=0;i<BASE_COUNT;i++) {
        result = convert.js2xml(jsData, { spaces: 4, compact: true })
    } 
    let endTime = Date.now() 
    let time = endTime - startTime
    print("xml_js_js2xml(js, options): " + time +" ms")  
    let xmlData = expectData.js2xml_data.replace(new RegExp('\v', 'g'), '    ')
    areEqual(xmlData, result) 
   
    // print(result)
} 
/* JavaScript objects are converted to xml strings */
function js2xml_Test_02() {    
    let jsData = {
        "elements": [{
            "type": "instruction", "name": "go", "attributes": {
            "to": "there"
            }
        }]
    }
    let result
    let startTime = Date.now()
    for (let i=0;i<1000;i++) {
        result = convert.js2xml(jsData)
    } 
    let endTime = Date.now() 
    let time = endTime - startTime
    print("xml_js_js2xml(js): " + time +" ms")   
    areEqual('<?go to="there"?>', result) 
   
    // print(result)
} 
 
/* Converts a json string to an xml string */
function json2xml_Test_01() {    
    let jsonData = {
      "ZohoCreator": {
          "applicationslist": {
              "application": [
                  {
                      "_attributes": {
                          "name": "testapp"
                      },
                      "formlist": {
                          "form": [
                              {
                                  "_attributes": {
                                      "name": "Untitled_Form"
                                  },
                                  "add": {
                                      "field": {
                                          "_attributes": {
                                              "name": "Subform_Single_Line"
                                          },
                                          "value": {
                                              "_text": "BEUHBALUGU"
                                          }
                                      }
                                  }
                              },
                              {
                                  "_attributes": {
                                      "name": "Untitled_Form"
                                  },
                                  "add": {
                                      "field": {
                                          "_attributes": {
                                              "name": "Subform_Single_Line"
                                          },
                                          "value": {
                                              "_text": "IF YOU CAN SEE THIS YOU DESERVE THE SUCC"
                                          }
                                      }
                                  }
                              }
                          ]
                      }
                  },
                  {
                      "_attributes": {
                          "name": "derp"
                      },
                      "formlist": {}
                  }
              ]
          }
      }
    };
    let result
    let startTime = Date.now()
    for (let i=0;i<BASE_COUNT;i++) {
        result = convert.json2xml(jsonData, {compact: true, spaces: 4, fullTagEmptyElement: true})
    } 
    let endTime = Date.now() 
    let time = endTime - startTime
    print("xml_js_json2xml(json, options): " + time +" ms")  
    let xmlData = expectData.json2xml_data 
    areEqual(xmlData, result) 
   
    // print(result)
} 
/* Converts a json string to an xml string */
function json2xml_Test_02() {    
    let jsonData = { "declaration": { "attributes": { "version": "1.0", "encoding": "utf-8" } } };
    let result
    let startTime = Date.now()
    for (let i=0;i<1000;i++) {
        result = convert.json2xml(jsonData)
    } 
    let endTime = Date.now() 
    let time = endTime - startTime
    print("xml_js_json2xml(json): " + time +" ms")   
    areEqual('<?xml version="1.0" encoding="utf-8"?>', result) 
   
    // print(result)
} 
  
/* Converts an xml format string to a json string */
function xml2json_Test_01() {  
    let xmlData =
    '<?xml version="1.0" encoding="utf-8"?>\n' +
    '<dp:ListServicesReply ReturnCode="0" xmlns:dp="http://www.cisco.com/vtg/diagnosticportal">\n' +
    '  <dp:Schema Version="1.0" />\n' +
    '  <dp:ServiceList>\n' +
    '    <dp:Service Name="Cisco ICM usgd1 LoggerA" Description="Provides Call Logging services for Instance usgd1" Status="Running" StartupType="Auto" LogOnAs="****" />\n' +
    '    <dp:Service Name="Cisco ICM Diagnostic Framework" Description="Provides a web-based diagnostic service for Cisco Unified ICM, Contact Center Enterprise application." Status="Running" StartupType="Auto" LogOnAs="LocalSystem" />\n' +
    '  </dp:ServiceList>\n' +
    '</dp:ListServicesReply>';   
    let result
    let startTime = Date.now()
    for (let i=0;i<BASE_COUNT;i++) {
        result = convert.xml2json(xmlData, { compact: true })
    } 
    let endTime = Date.now() 
    let time = endTime - startTime
    print("xml_js_xml2json(xml, userOptions): " + time +" ms")  
    const jsonData = JSON.stringify(expectData.xml2json_data)
    areEqual(jsonData, result) 
   
    // print(result)
}
/* Converts an xml format string to a json string */
function xml2json_Test_02() {  
    let xmlData =
    '<![CDATA[ \t <foo></bar> \t ]]>';   
    let result
    let startTime = Date.now()
    for (let i=0;i<BASE_COUNT;i++) {
        result = convert.xml2json(xmlData)
    } 
    let endTime = Date.now() 
    let time = endTime - startTime
    print("xml_js_xml2json(xml): " + time +" ms")  
    const jsonData = JSON.stringify({ "elements": [{ "type": "cdata", "cdata": " \t <foo></bar> \t " }] })
    areEqual(jsonData, result) 
   
    // print(result)
} 

/* The xml string is reconstructed into the Message body through the message body builder, combined with the data */
function xml2js_Test_01() {  
    let  xmlData =
    '<d:multistatus xmlns:d="DAV:">\n' +
    '  <d:response>\n' +
    '      <d:href>/</d:href>\n' +
    '      <d:propstat>\n' +
    '          <d:prop>\n' +
    '              <d:current-user-principal>\n' +
    '                  <d:href>/principals/users/johndoe/</d:href>\n' +
    '              </d:current-user-principal>\n' +
    '          </d:prop>\n' +
    '          <d:status>HTTP/1.1 200 OK</d:status>\n' +
    '      </d:propstat>\n' +
    '  </d:response>\n' +
    '</d:multistatus>';
    let result
    let startTime = Date.now()
    for (let i=0;i<BASE_COUNT;i++) {
        result = convert.xml2js(xmlData, { compact: true, resolveNamespace: false })
    } 
    let endTime = Date.now() 
    let time = endTime - startTime
    print("xml_js_xml2js(xml, userOptions): " + time +" ms")  
    const jsData = expectData.xml2js_data
    areEqual(JSON.stringify(jsData), JSON.stringify(result)) 
   
    // print(JSON.stringify(result))
} 
/* The xml string is reconstructed into the Message body through the message body builder, combined with the data */
function xml2js_Test_02() {  
    let  xmlData = '<a x="1.234" y="It\'s"/>';
    let result
    let startTime = Date.now()
    for (let i=0;i<BASE_COUNT;i++) {
        result = convert.xml2js(xmlData)
    } 
    let endTime = Date.now() 
    let time = endTime - startTime
    print("xml_js_xml2js(xml): " + time +" ms")  
    const jsData = { "elements": [{ "type": "element", "name": "a", "attributes": { "x": "1.234", "y": "It\'s" } }] }
    areEqual(JSON.stringify(jsData), JSON.stringify(result)) 
   
    // print(JSON.stringify(result))
} 
 
/* Expected results and actual results verification  */
function areEqual(expected, actual) {
    // If expected and actual are both NaN, consider them equal.
    if (expected === actual || expected !== expected && actual !== actual) {
        // print('Success')
    } else {
        let error = 
        '  Failed areEqual test' +
        '  Expected: ' + expected +
        '  Actual:   ' + actual
        ;
        throw(error) 
    }
}

// function print(s){
//     console.log(s)
// }

/*  Benchmark  */
function xml_jsRun() { 
    js2xml_Test_01()   
    js2xml_Test_02()   

    json2xml_Test_01()  
    json2xml_Test_02()  

    xml2json_Test_01()   
    xml2json_Test_02()

    xml2js_Test_01() 
    xml2js_Test_02()   
    
} 

let loopCountForPreheat = 1;
for (let i = 0; i < loopCountForPreheat; i++) {
    xml_jsRun()
}

ArkTools.waitAllJitCompileFinish();

xml_jsRun()